﻿using System;
using System.Activities;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Markup;
using WFExtended.Activities.Designers;

namespace WFExtended.Activities
{
    /// <summary>
    /// Build a WCF Proxy with a Uri and binding
    /// <code>
    /// DelegateInArgument<WcfProxy<IMockService>> proxy = new DelegateInArgument<WcfProxy<IMockService>>(); <br />
    /// InArgument<Uri> uri = new InArgument<Uri>(); <br />
    /// InArgument<Binding> binding = new InArgument<Binding>(); <br />
    /// Activity workflow = new WcfUriProxy<IMockService>() <br />
    /// &nbsp; { <br />
    /// &nbsp; &nbsp; Uri = uri <br />
    /// &nbsp; &nbsp; Binding = binding <br />
    /// &nbsp; &nbsp; Body = new System.Activities.ActivityAction<WcfProxy<IMockService>>() <br />
    /// &nbsp; &nbsp; { <br />
    /// &nbsp; &nbsp; &nbsp; Argument = proxy, <br />
    /// &nbsp; &nbsp; &nbsp; Handler = new Sequence() <br />
    /// &nbsp; &nbsp; &nbsp; { <br />
    /// &nbsp; &nbsp; &nbsp; } <br />
    /// &nbsp; &nbsp; } <br />
    ///&nbsp;  } <br />
    /// </code>
    /// </summary>
    /// <typeparam name="T">Type of the Service Contrac</typeparam>
    [ToolboxBitmapAttribute(typeof(EntryPoint), "Resources.WcfContractProxyToolbox.bmp")]
    [Designer(typeof(WcfContractProxyDesigner))]
    [ContentProperty("Body")]
    [Description("Build a WCF Proxy with a Uri and binding for the service contract T")]
    public class WcfUriProxy<T> : AWcfProxyActivity<T>
        where T : class
    {
        /// <summary>
        /// Get Or set the Communication Binding
        /// <remarks>
        /// Required Argument
        /// </remarks>
        /// </summary>
        [Browsable(true)]
        [RequiredArgument]
        [Category("Proxy")]
        [Description("Required Argument")]
        public InArgument<Binding> Binding { get; set; }

        /// <summary>
        /// Get or Set the address of the service
        /// <remarks>
        /// Required Argument
        /// </remarks>
        /// </summary>
        [Browsable(true)]
        [RequiredArgument]
        [Category("Endpoint")]
        [Description("Get or Set the address of the service")]
        public InArgument<Uri> Uri { get; set; }

        /// <summary>
        /// Get or Set the authentication settings
        /// </summary>
        [Browsable(true)]
        [Category("Endpoint")]
        [Description("Get or Set the authentication settings")]
        public InArgument<EndpointIdentity> Identity { get; set; }


        /// <summary>
        /// Get the Service Endpoint
        /// </summary>
        /// <param name="context">The execution context in which the activity executes</param>
        /// <returns>Return the Service Endpoint</returns>
        protected override System.ServiceModel.Description.ServiceEndpoint GetServiceEndpoint(NativeActivityContext context)
        {
            var headers = Headers.Get(context);
            if (headers == null)
                headers = new List<AddressHeader>();
            return new ServiceEndpoint(
                 ContractDescription.GetContract(typeof(T)),
                 Binding.Get(context),
                 new EndpointAddress(
                     Uri.Get(context),
                     Identity.Get(context),
                     headers.ToArray()));
        }
    }
}
